﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __8CD539A0_E036_4584_9B18_BED1095E41CB__
#define __8CD539A0_E036_4584_9B18_BED1095E41CB__

#include "../tools/head.h"
#include "include_odbc.h"
#include "err_info.h"

namespace xos_odbc
{

    class odbc_stmt : public xos_stl::mem_item< xos::release_impl< odbc_stmt >, thread_lock >,
        public i_stmt
    {
    public:
        typedef xos::release_impl< odbc_stmt > T;

    public:
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        static int get_addr( POOL *** pppPool, LIST *** pppList );

    public:
        odbc_stmt();
        ~odbc_stmt();

    public:
        // 
        // 得到最近的错误信息
        // 
        int get_last_err_info( char * lpszInfo, int nSize, int * lpnInfoLen, int * lpnLenNeeded );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, enumDirection eType, enumValueType eValueType,
            enumValueType eParamType, int ColSize,
            int DecimalDigits,
            void * ParamValuePtr,
            int BufLen,
            xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, const char * lpszData, int nNoop, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, xos::xos_i64 * lpnData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, xos::xos_i32 * lpnData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, xos::xos_i16 * lpnData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, xos::xos_i8 * lpnData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, xos::xos_u64 * lpnData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, xos::xos_u32 * lpnData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, xos::xos_u16 * lpnData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, xos::xos_u8 * lpnData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, bool * lpnData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, float * lpfData, int nDigitNum, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输入参数
        // 
        int bind_param( int nCol, double * lpdData, int nDigitNum, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 翻译一下odbc返回的StrLen_or_IndPtr为i_stmt中的enumLenOrPtr类型
        // 
        int translate_strlen_or_indptr( xos::xos_int StrLen_or_IndPtr, xos::xos_int * lp_StrLen_or_IndPtr );

        // 
        // 直接运行sql
        // 
        //  0 : success. 
        //  1 : running. 
        // -1 : failed
        // 
        int execute_direct( const char * lpszSql );

        //
        // 编译sql
        // 
        //  0 : success. 
        //  1 : running. 
        // -1 : failed
        // 
        int prepare_sql( const char * lpszSql );

        // 
        // 绑定输入后执行sql语句写入
        // 
        //  0 : success. 
        //  1 : running. 
        // -1 : failed
        // 
        int execute();

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, enumValueType eType, void * pBufByte,
            int nBufSize,
            xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, char * lpData, int nBufSize, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, xos::xos_i64 * lpData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, xos::xos_i32 * lpData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, xos::xos_i16 * lpData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, xos::xos_i8 * lpData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, xos::xos_u64 * lpData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, xos::xos_u32 * lpData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, xos::xos_u16 * lpData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, xos::xos_u8 * lpData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, bool * lpData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, float * lpData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 绑定输出参数
        // 
        int bind_colum( int nCol, double * lpData, xos::xos_int * StrLen_or_IndPtr );

        // 
        // 设置是否异步执行sql
        // 
        int set_async( bool bAsync );

        // 
        // 下一结果集
        // 
        int next_results();

        // 
        //  0 : success
        //  1 : pending
        //  2 : no data
        // -1 : failed
        // 
        int fetch();

        // 
        // 执行DML后，影响的行数
        // 
        int get_affect_row_num( long long * lpnNum );

        // 
        // 得到结果集行数
        // 
        int get_result_row_num( long long * lpnNum );

        // 
        // 查询结果集中的列数
        // 
        int get_result_col_num( int * lpnNum );

        // 
        // 查询结果集中的列数,index从0开始
        // 
        int get_col_name( int nIndex, char * lpszName, int nLen );

    protected:
        int from_len_or_ptr( SQLLEN LenOrPtr, SQLLEN * lpLenOrPtr );
        int to_len_or_ptr( SQLLEN LenOrPtr, SQLLEN * lpLenOrPtr );
        int to_sql_io_type( int nInputType, int * lpnOutType );
        int to_c_type( int nInputType, int * lpnOutType );

    public:
        int set_handle( SQLHANDLE hStmt );
        SQLHANDLE handle();
        int init();
        int term();

    private:
        int init_data();

    private:
        std::string m_sql;
        SQLHANDLE m_hStmt;
        err_info m_err;
        bool m_bAsync;

    };

} // xos_odbc

#endif // __8CD539A0_E036_4584_9B18_BED1095E41CB__
